#ifndef _MATRIXMUL_KERNEL_H_
#define _MATRIXMUL_KERNEL_H_

#include <stdio.h>
#include "common.cuh"

__global__ void mulMatrix( float* A, float* B, float* C,  int wA, int wB)
{
    int bx = blockIdx.x;
    int by = blockIdx.y;
    int tx = threadIdx.x;
    int ty = threadIdx.y;
	const int widthC = wB;
    int aBegin = wA * BLOCK_SIZE_Y * by;
    int aEnd   = aBegin + wA - 1;
    int aStep  = BLOCK_SIZE_X;
    int bBegin = BLOCK_SIZE_Y * bx;
    int bStep  = BLOCK_SIZE_X * wB;
    float c = 0.f;

	__shared__ float As[BLOCK_SIZE_Y][BLOCK_SIZE_X];
    __shared__ float Bs[BLOCK_SIZE_X][BLOCK_SIZE_Y];

    for (int a = aBegin, b = bBegin;
             a <= aEnd;
             a += aStep, b += bStep) {
        
        As[ty][tx] = A[a + wA * ty + tx];
        Bs[ty][tx] = B[b + wB * ty + tx];

        __syncthreads();
        for (int k = 0; k < BLOCK_SIZE_X; ++k)
        {
            c += As[ty][k] * Bs[k][tx];
        }
        __syncthreads();
    }

    int baseC = widthC * BLOCK_SIZE_Y * blockIdx.y + BLOCK_SIZE_X * blockIdx.x;
    C[baseC + widthC * threadIdx.y + threadIdx.x] = c;
}

#endif 
